// Title of toolset: Luts Macros and Tools Updater.txt 
// Revision version 1.1a: 03/07/2009
// First version: 17/11/2006 

// Description:

// The "Luts Macros and Tools Updater" tool set perfoms a live-updating/restoring of the following ImageJ macros repertories:
// - /macros
// - /macros/examples
// - /macros/tools
// - /macros/toolsets
// - /luts
//------------------------------------
// Author : Gilles Carpentier
// Faculte des Sciences et Technologies,
// Universite Paris 12 Val de Marne, France.
//------------------------------------

var weberror="distant file not found";
var distantmacrosrep = "http://rsb.info.nih.gov/ij/macros/";
var distantmacrosexamplerep = "http://rsb.info.nih.gov/ij/macros/examples/"; 
var distanttoolsrep = "http://rsb.info.nih.gov/ij/macros/tools/";
var distanttoolsetsrep = "http://rsb.info.nih.gov/ij/macros/toolsets/";
var distribLutFolder = "http://image.bio.methods.free.fr/ij/luts/distribution/";
var collectionLutFolder = "http://image.bio.methods.free.fr/ij/luts/IJSiteMainCollection/";
var otherLutsFolder = "http://image.bio.methods.free.fr/ij/luts/OtherLuts/";
var urllist="http://image.bio.methods.free.fr/ij/ijupdatetest/ListOfMacros.txt";distantmacrolink = "";
var KindOfMacro=0,report=0,updates=0,nMacroinL=0,nToolinL=0,nToolsetsinL=0,nMacroExampleinL=0,TheReport="";
var onlinedoclink = "http://image.bio.methods.free.fr/ImageJ/?Luts-Macros-and-Tools-Updater.html";
var distantlutsrep = "http://image.bio.methods.free.fr/ij/luts/"; distantmacrolink = ""; nLutsinL=0;
var urllistoflut="http://image.bio.methods.free.fr/ij/ijupdatetest/ListOfLuts.txt";distantmacrolink = ""; 
var demoimagename = "blobs.gif";
var stopthemacro=0;
var errorNetMessage ="Error: "; 
var macrosFolder = "http://rsb.info.nih.gov/ij/macros/";
var exampleFolder = "http://rsb.info.nih.gov/ij/macros/examples/";
var toolsFolder = "http://rsb.info.nih.gov/ij/macros/tools/";
var toolsetsFolder = "http://rsb.info.nih.gov/ij/macros/toolsets/";
var totalMacroNumber=0, totallutnumber=0, visuchoice="Palette";
var duplicateChoice=0;
var updateMethods= newArray("Update from a static list updated every month","Update by exploring the web repertories");
var updateMethod = "Update by exploring the web repertories";
var duplicateMessage = "";

var xx = requires142p(); // check version at install time
function requires142p() {requires("1.42p"); return 0; }

var installx = testinstal ();

macro "Stop Lut Scan Tool - Ccc" {stopthemacro=1;}

// macro updater menu tool
var uCmds = newMenu("Macro, Tools and Toolsets Updater Menu Tool",newArray("Macro, Tools and Toolsets Updater","-","Get the static list of available macros, tools and toolsets","Get the list of available macros, tools and toolsets by web exploration"));
macro "Macro, Tools and Toolsets Updater Menu Tool - CcccD5fD6fD7fD8fD9fC78bD17D19D2aD33D37D3bD42D4cD75D95DceDd5Dd9De6Df7Df9CddeDa3C36bD27D28D3aD57D58D59D66D76D77D86D87Da7Db8Dd6De8De9CeeeD00D01D02D04D06D07D08D09D0bD0dD0fD10D11D12D14D1bD1dD1fD20D21D22D2dD30D31D32D40D46D47D48D49D50D5bD60D70D71D72D74D7dD80D81D82D84D8dD90D91D92D94D9dDa0Da1Da2Da4Db0Db1DbbDc0Dc1Dc6Dc7Dc8Dc9Dd0Dd1Dd2De0De1De2DedDf0Df1Df2Df4DfbDfdDffC8beD3cD3dD4dD5aD6aD79D7aD7bD85D8bD9aDaaDc3Dc4Dd3Dd4CeeeD03D05D0aD0cD0eD13D15D1cD1eD23D2eD3eD4aD55D6cD73D7cD7eD83D8cD8eD93D9cD9eDb5DcaDdeDe3DeeDf3Df5DfcDfeC559D18D26D34D35D36D41D51D61DafDbfDcfDdaDdbDddDeaDf8CcddD2fD5cD6dD6eDabDb2Db4Dc2DefC99bD16D24D39D45D54D56D64D65Da5DacDb6DbcDcbDd7DecDfaCdefD67D8aC59dD29D2bD68D69D78D88D96D97D98D99Da6Da8Da9Db9De5De7CacdD1aD2cD38D4bD4eD5dD5eD6bD89D9bDb3DbaDc5Dd8De4Df6C348D25D43D44Db7DccDdcDebCcccD3fD4fDdf"{
	cmd = getArgument();
	if (cmd!="-" && cmd == "Macro, Tools and Toolsets Updater") {MacroToolsToolsetsUpdater ();}
	if (cmd!="-" && cmd == "Get the static list of available macros, tools and toolsets") {GetTheListofAvailableMacros ();}
	if (cmd!="-" && cmd == "Get the list of available macros, tools and toolsets by web exploration") {GetTheListofAvailableMacrosweb ();}
}

var luts2 = lastInstalledLutVisu2();
var vCmds = newMenu("LUTs Updater Menu Tool",luts2);
macro "LUTs Updater Menu Tool - Ce40D40D41D42D43D44D45D46D47D48D49D4aD4bD4cD4dD4eD4fCfffD80D81D82D83D84D85D86D87D88D89D8aD8bD8cD8dD8eD8fD90D91D92D93D94D95D96D97D98D99D9aD9bD9cD9dD9eD9fDa0Da1Da2Da3Da4Da5Da6Da7Da8Da9DaaDabDacDadDaeDafDb0Db1Db2Db3Db4Db5Db6Db7Db8Db9DbaDbbDbcDbdDbeDbfDc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9DcaDcbDccDcdDceDcfDd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9DdaDdbDdcDddDdeDdfDe0De1De2De3De4De5De6De7De8De9DeaDebDecDedDeeDefDf0Df1Df2Df3Df4Df5Df6Df7Df8Df9DfaDfbDfcDfdDfeDffCd13D30D31D32D33D34D35D36D37D38D39D3aD3bD3cD3dD3eD3fCf90D60D61D62D63D64D65D66D67D68D69D6aD6bD6cD6dD6eD6fC60dD00D01D02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eD0fCf70D50D51D52D53D54D55D56D57D58D59D5aD5bD5cD5dD5eD5fCb07D20D21D22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eD2fCfb0D70D71D72D73D74D75D76D77D78D79D7aD7bD7cD7dD7eD7fC90bD10D11D12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eD1fT8d12U"{
	cmd = getArgument();
	if (cmd!="-" && cmd == "LUTs Updater") {LUTsUpdater ();}
	if (cmd!="-" && cmd == "Get the static list of available LUTs") {GetthelistofavailableLUTs ();}
	if (cmd!="-" && cmd == "Get the list of available LUTs by web exploration") {GetTheListofAvailableLutsweb();}
	if (cmd!="-" && cmd == "Show installed luts as \"Palette\"") {lutsPalette (0,"");}
	if (cmd!="-" && cmd != "LUTs Updater" && cmd !="No last luts installed list file found" && cmd != "Record this tool into the \"toolsets\" folder, to use this menu tool." && cmd != "List of new installed LUTs:" && cmd != "LUTs Updater" && cmd != "Get the static list of available LUTs" && cmd !="Get the list of available LUTs by web exploration" && cmd !="Show installed luts as \"Palette\"") {
		image=checkForImage(cmd);
		if (nImages > 0) {selectImage(image); rename (cmd);}
		run(cmd);
	}
}

macro "On Line Documentation Action Tool - C000Da9DadDb6DbdDc5Dc6Dd3Dd4Dd5Dd6DddC20fD11D12D13D14D15D16D17D18D19D1aD1bD1cD1dD1eD1fC0f3D42D43D44D45D46D47D48D49D4aD4bD4cD4dD4eD4fC0feD32D33D34D35D36D37D38D39D3aD3bD3cD3dD3eC444DdeDefC73fD01Cfd0D62D63D64D65D66D67D68D69D6aD6bD6cD6dD6eCeeeD90D95Da1Da4Db0Db2Db3De0De8Df0Df7DfaC222DeeC06fD22D23D24D25D26D27D28D29D2aD2bD2cD2dD2eC7f0D52D53D54D55D56D57D58D59D5aD5bD5cD5dD5eCcccDbfDf9Cf74D70Ca99D97C888Da8CfffD9bD9cC000Dc4Dd2C64fD10C0f4D41C0ffD31D3fCf40D71D72D73D74D75D76D77D78D79D7aD7bD7cD7dD7eD7fCa7fD00Cfd0D61D6fCfefD91C444Db5DdaDe9C06fD21D2fC7f0D51D5fCeddD96Cf88D82D83D84D85D8bD8cCaaaDccDeaDfdC999DcfCfffD9fDafDb1Db8De1C666Dc7C84fD02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eC333Da6Da7DaaDb9DbcDd9DdcCdddD9aDa2Da3Dc8DdbDecCaaaDabDaeDc1De3De4De5De6Cf89D8dC222DcdDedDfeDffC4ffD30CfffDebDf1Df2Df3Df4Df5Df6DfcC48fD20C4f6D40CeeeD92D93D94Da0DcbDf8DfbCbbbDb4Dd8C9f4D50C555Dc2C73fD0fC333DbbDc3Dc9Dd1CdddDe7Cf89D81D86D8aD8fC111DbaDd7CdeeDa5CbbbDb7Dc0De2Cf99D87D88D89C777DacDcaCcbbD9eCfaaD80C999D98Cf89D8eC999D9dC766D99C555DceC888DbeCfd4D60C777DdfC666Dd0"{
	netTest ();
	showMessageWithCancel  ("A notice is avaible on line. Open it with your default web browser?");
	run("URL...", "url=["+onlinedoclink +"]");
} 

macro "Version and Update Infos Action Tool - C0589T1e16VTcf13?" {
	VersionInfos ();
}

macro "About Luts Macros and Tools Updater Action Tool - C000D84Cb9fD25De7CaaaD14D2dDa0DafDecDfaCedfD49D4aD4bD4cD58D68D9bDb9DbaDbbDbcC889D2cDebCddfD52CcccD0bD22CeeeD00D03D0cD0fD10D1fD20D2fD30D40Dc0Dd0DdfDe0DefDf0Df1Df2Df3DfcDfeDffC666D07D70CdcfD34D35Dc4CbacD86D91CfefD6bD6dD7cD8cD8dD8eD9cD9dDadC97aDd3De5CedfD99CeeeD01D02D04D0dD0eD11D12D1eD21D3fDcfDd1De1De2DeeDf4DfdCfefD7dC545D94Da5CdbeDa4Da7CbabD05D50DaeCfefD7eC98aD32Da1CecfD39D3aD3bD46D48D57D67Da8Db6Db8Dc9DcaDcbDccCdcdD81C878D1bD60D65CdcfD29D36D38D47D77Db7Dc8Dd9DdaCcbcD7aDbfDc1De3C98bD16D24D75DeaCedfD56D66D73D76D83D93Da3C212D7bD88D96D97CcaeD26D3cDdbCaaaD3eD5fCfdfD59C889D15D1aD78Dc2CdcfD45Db4Db5Dc6CdddD13D31D4fDdeDedDfbC777D09D7fD85D90Df7CeceDbdCbadD18D55Db2De9Ca9aD5eDcdDceDdcC656D08D64D80D87D8bCdbfD28D2aD37Dc7Dd8CbbbD1cD42Dd2Df5CfdfD5aD5bD5cD5dD69D6aD6cD9aDa9DabDacC999D0aD41DddDf6CdddD1dD2eD9eDb0C888D06D4eD6fD9fDf9CcbdD54D71D98Dc3Ca9dD17D19Dd4De6C000D74D79D95CcafDd5Dd6De8CedfD62D72D92C889D51Db1DbeCedfD53D63Da2CdcdD6eC777D8fDf8CdcfD43D44Db3Dc5CbadD2bD33C99aD23De4C545D89Da6CcbfD27Dd7CbabD61CedfD82DaaC98aD3dCdceD4dD8a" {
	about1();
}

function testinstal () {
	nomdetool =  "Luts Macros and Tools Updater.txt";
	nomdedev = "Luts Macros and Tools Updater-dev.txt";
	locdev ="tools";
	destidev= "toolsets";
	pluginfoldername= "Macros";
	endinstall (nomdetool,nomdedev,locdev,destidev,pluginfoldername);
	return nomdetool;
}

function MacroToolsToolsetsUpdater () {
	distantmacrolink = urllist;  checkLocation ();
	netTest ();
	Dialog.create("Macro & Tool Updater");
	Dialog.addMessage("The updater will look for new available macros, tools and toolsets.");
	Dialog.addChoice("Choose the update method",updateMethods ,updateMethod);
	Dialog.addMessage("\nChoose Updater Options:");
	Dialog.addCheckbox("- Check for macros, tools and toolsets updates (longer query):", 0);
	Dialog.addCheckbox("- Ignore duplicates (moved macros):", duplicateChoice);	
	Dialog.addMessage("This option check for modifications, corrections or improvements \nfor the Macros, Tool and Toolsets already installed onto your \nImageJ version.");
	Dialog.addMessage("\n ");
	Dialog.addCheckbox("- Make an installation report.", 1);
	Dialog.show();
	updateMethod=Dialog.getChoice();
	updates= Dialog.getCheckbox();
	duplicateChoice= Dialog.getCheckbox();
	report= Dialog.getCheckbox();
	// To get the contents of the distant list of macros.
	showStatus("Internet link...");
	if (updateMethod == updateMethods[0]) {
		macrotextnih =File.openUrlAsString(distantmacrolink);
		showStatus("");
	}
	if (updateMethod == updateMethods[1]) {
		macrotextnih =getListOfOnlineMacros (0);
		showStatus("");
	}
	// To obtain the separated lists of macros and tools from the distant file or web list.
	lines=split(macrotextnih,"\n");
	getMandTNumber (lines);
	lMacro = newArray(nMacroinL); lTool = newArray(nToolinL);  lToolsets = newArray(nToolsetsinL); lMacroExample=newArray(nMacroExampleinL);
	lMacro = lPlace (lines,lMacro,"Macro "); lTool = lPlace (lines,lTool,"Tool "); lToolsets = lPlace (lines,lToolsets,"Toolset ");lMacroExample = lPlace (lines,lMacroExample,"Example "); 

	// To get the contents of local ImageJ (Macros, Tools, Toolsets) folders, into separated lists of macros, tools and toolsets.
	macrosfolder = "";alert=0;
	if (getDirectory("macros") == "") {
		// built a macros repertory
		macrobuilt= getDirectory("startup") ;
		MacroDir = macrobuilt +"macros" +File.separator;
		File.makeDirectory(MacroDir);
		if (!File.exists(MacroDir)) exit ("Unable to create the \" macros \" directory, something wrong in the ImageJ folder.\nTry again after restarting Image.");
		macrosfolder = MacroDir; alert =1;
	}
	if (macrosfolder == "") macrosfolder = getDirectory("macros");
	macrostoolslocation = macrosfolder + "tools" +File.separator;
	if (File.isDirectory(macrostoolslocation) == 0) {
		File.makeDirectory(macrostoolslocation);
		if (!File.exists(macrostoolslocation)) exit("Unable to create the \" tools \" directory, something wrong in the ImageJ folder.\nTry again after restarting Image.");
	}
	macrosexamplelocation = macrosfolder + "examples"+File.separator;
	if (File.isDirectory(macrosexamplelocation) == 0) {
		File.makeDirectory(macrosexamplelocation);
		if (!File.exists(macrosexamplelocation)) exit("Unable to create the \" examples \" directory, something wrong in the ImageJ folder.\nTry again after restarting Image.");
	}
	macrostoolsetlocation = macrosfolder + "toolsets"+File.separator;;
	if (File.isDirectory(macrostoolsetlocation) == 0) {
		File.makeDirectory(macrostoolsetlocation);
		if (!File.exists(macrostoolsetlocation)) exit("Unable to create the \" toolsets \" directory, something wrong in the ImageJ folder\nTry again after restarting Image.");
	}
	listofmacro = getFileList(macrosfolder); listoftools = getFileList(macrostoolslocation);listoftoolsets = getFileList(macrostoolsetlocation);listofexamples = getFileList(macrosexamplelocation); 
	NbMacro= getMacroNumber (listofmacro); NbTools= getMacroNumber (listoftools); NbToolsets= getMacroNumber (listoftoolsets); NbExamples=getMacroNumber(listofexamples); NbToolsandMacros=(NbMacro + NbTools + NbToolsets + NbExamples); 
	FMacros = newArray(NbMacro); FTools =newArray(NbTools); FToolsets =newArray(NbToolsets); FExamples=newArray(NbExamples); 
	FMacros = lPlace (listofmacro,FMacros,""); FTools = lPlace (listoftools,FTools,""); FToolsets =lPlace (listoftoolsets,FToolsets,""); FExamples=lPlace (listofexamples,FExamples,"");
	// To get the new macros, tools and toolsets present in the list, not present into the local ImageJ .
	nbNewMacro= (nMacroinL - nbThings(lMacro,FMacros)); nbNewTools= (nToolinL - nbThings(lTool,FTools));nbNewToolsets= (nToolsetsinL - nbThings(lToolsets,FToolsets)); nbNewExamples= (nMacroExampleinL - nbThings(lMacroExample,FExamples));
	NewMacros = newArray(nbNewMacro); NewTools =newArray(nbNewTools);NewToolsets =newArray(nbNewToolsets); NewExamples=newArray(nbNewExamples); 
	NewMacros = PlaceNewThings (lMacro,FMacros,NewMacros); NewTools = PlaceNewThings (lTool,FTools,NewTools);NewToolsets = PlaceNewThings (lToolsets,FToolsets,NewToolsets); NewExamples=PlaceNewThings (lMacroExample,FExamples,NewExamples);
	// search for moved macros
	macrodoublonsExample= nbThings(NewMacros,listofexamples); lmacrodoublonsExample =newArray (macrodoublonsExample); lmacrodoublonsExample=PlaceDuplicate (listofexamples,NewMacros,lmacrodoublonsExample);	
	macrodoublonsTools= nbThings(NewMacros,listoftools); lmacrodoublonsTools=newArray (macrodoublonsTools); lmacrodoublonsTools=PlaceDuplicate (listoftools,NewMacros,lmacrodoublonsTools);
	macrodoublonsToolsets= nbThings(NewMacros,listoftoolsets); lmacrodoublonsToolsets=newArray (macrodoublonsToolsets); lmacrodoublonsToolsets=PlaceDuplicate (listoftoolsets,NewMacros,lmacrodoublonsToolsets);
	// search for moved examples
	exampledoublonsMacro= nbThings(NewExamples,listofmacro); lexampledoublonsMacro =newArray (exampledoublonsMacro); lexampledoublonsMacro=PlaceDuplicate (listofmacro,NewExamples,lexampledoublonsMacro);
	exampledoublonsTools= nbThings(NewExamples,listoftools); lexampledoublonsTools =newArray (exampledoublonsTools); lexampledoublonsTools=PlaceDuplicate (listoftools,NewExamples,lexampledoublonsTools);
	exampledoublonsToolsets= nbThings(NewExamples,listoftoolsets); lexampledoublonsToolsets =newArray (exampledoublonsToolsets); lexampledoublonsToolsets=PlaceDuplicate (listoftoolsets,NewExamples,lexampledoublonsToolsets);	
	// search for moved tools 
	toolsdoublonsMacro= nbThings(NewTools,listofmacro); ltoolsdoublonsMacro =newArray (toolsdoublonsMacro); ltoolsdoublonsMacro=PlaceDuplicate (listofmacro,NewTools,ltoolsdoublonsMacro);
	toolsdoublonsExample= nbThings(NewTools,listofexamples); ltoolsdoublonsExample =newArray (toolsdoublonsExample); ltoolsdoublonsExample=PlaceDuplicate (listofexamples,NewTools,ltoolsdoublonsExample);
	toolsdoublonsToolsets= nbThings(NewTools,listoftoolsets); ltoolsdoublonsToolsets =newArray (toolsdoublonsToolsets); ltoolsdoublonsToolsets=PlaceDuplicate (listoftoolsets,NewTools,ltoolsdoublonsToolsets);	
	//search for moved  duplicated
	toolsetdoublonsMacro= nbThings(NewToolsets,listofmacro); ltoolsetdoublonsMacro =newArray (toolsetdoublonsMacro); ltoolsetdoublonsMacro=PlaceDuplicate (listofmacro,NewToolsets,ltoolsetdoublonsMacro);
	toolsetdoublonsExample= nbThings(NewToolsets,listofexamples); ltoolsetdoublonsExample =newArray (toolsetdoublonsExample); ltoolsetdoublonsExample=PlaceDuplicate (listofexamples,NewToolsets,ltoolsetdoublonsExample);
	toolsetdoublonsTool= nbThings(NewToolsets,listoftools); ltoolsetdoublonsTool =newArray (toolsetdoublonsTool); ltoolsetdoublonsTool=PlaceDuplicate (listoftools,NewToolsets,ltoolsetdoublonsTool);
	
	if (duplicateChoice == 0) {	
		// resample the new macros lists
		NewMacros2=NewMacros ; NewTools2=NewTools; NewToolsets2=NewToolsets; NewExamples2=NewExamples;
		if (nbNewMacro > 0  && macrodoublonsExample>0 ) {NewMacros2 =reSampling (NewMacros2,lmacrodoublonsExample);}
		if (nbNewMacro > 0  && macrodoublonsTools>0 ) {NewMacros2 =reSampling (NewMacros2,lmacrodoublonsTools);}
		if (nbNewMacro > 0  && macrodoublonsToolsets>0 ) {NewMacros2 =reSampling (NewMacros2,lmacrodoublonsToolsets);}
		
		if (nbNewTools > 0  && toolsdoublonsMacro>0 ) {NewTools2 =reSampling (NewTools2,ltoolsdoublonsMacro);}
		if (nbNewTools > 0  && toolsdoublonsExample>0 ) {NewTools2 =reSampling (NewTools2,ltoolsdoublonsExample);}		
		if (nbNewTools > 0  && toolsdoublonsToolsets>0 ) {NewTools2 =reSampling (NewTools2,ltoolsdoublonsToolsets);}
		
		if (nbNewToolsets > 0  && toolsetdoublonsMacro>0 ) {NewToolsets2 =reSampling (NewToolsets2,ltoolsetdoublonsMacro);}
		if (nbNewToolsets > 0  && toolsetdoublonsExample>0 ) {NewToolsets2 =reSampling (NewToolsets2,ltoolsetdoublonsExample);}		
		if (nbNewToolsets > 0  && toolsetdoublonsTool>0 ) {NewToolsets2 =reSampling (NewToolsets2,ltoolsetdoublonsTool);}
		
		if (nbNewExamples > 0  && exampledoublonsMacro>0 ) {NewExamples2 =reSampling (NewExamples2,lexampledoublonsMacro);}
		if (nbNewExamples > 0  && exampledoublonsTools>0 ) {NewExamples2 =reSampling (NewExamples2,lexampledoublonsTools);}
		if (nbNewExamples > 0  && exampledoublonsToolsets>0 ) {NewExamples2 =reSampling (NewExamples2,lexampledoublonsToolsets);}		
		var NewMacros=newArray (lenghtResampled (NewMacros2));  
		var NewTools=newArray (lenghtResampled (NewTools2));
		var NewToolsets=newArray (lenghtResampled (NewToolsets2)); 
		var NewExamples=newArray (lenghtResampled (NewExamples2)); 
		NewMacros=listResampled (NewMacros2,NewMacros);
		NewTools =listResampled (NewTools2,NewTools);
		NewExamples =listResampled (NewExamples2,NewExamples);
		NewToolsets =listResampled (NewToolsets2,NewToolsets);		
	}
	// To get the new macros and tool updates available for the local ImageJ macros and tools.
	if(updates==1) {
		SortedNewMacros = newArray(NbMacro);
		UpdatedMacro = newArray(Nbmacroupdates (FMacros,lMacro,distantmacrosrep,macrosfolder,SortedNewMacros));
		UpdatedMacro = placeUpdatemacro(UpdatedMacro,FMacros,SortedNewMacros);
		SortedNewTools = newArray(NbTools);
		UpdatedTool = newArray(Nbmacroupdates (FTools,lTool,distanttoolsrep,macrostoolslocation,SortedNewTools));
		UpdatedTool = placeUpdatemacro(UpdatedTool,FTools,SortedNewTools);
		SortedNewToolsets = newArray(NbToolsets);
		UpdatedToolsets = newArray(Nbmacroupdates (FToolsets,lToolsets,distanttoolsetsrep,macrostoolsetlocation,SortedNewToolsets));
		UpdatedToolsets = placeUpdatemacro(UpdatedToolsets,FToolsets,SortedNewToolsets);
		SortedNewExamples = newArray(NbExamples); 
		UpdatedExamples = newArray(Nbmacroupdates (FExamples,lMacroExample,distantmacrosexamplerep,macrosexamplelocation,SortedNewExamples));
		UpdatedExamples = placeUpdatemacro(UpdatedExamples,FExamples,SortedNewExamples);
	} else {UpdatedMacro=0;UpdatedTool=0;UpdatedToolsets=0;UpdatedExamples=0;} 
	// To make a dialog box to the user.
	Messagenew=""; messageupdat="";
	message1="- No Macro, Example, Tool or Toolset update available.";
	message2="- There is no new Macro, Example, Tool or Toolset available.";
	message3="- Macros, Example, Tools and Toolsets Updates were not queried.";
	if ((NewMacros.length + NewTools.length +NewToolsets.length + NewExamples.length) > 0) {
				Messagenew = "- There are "+ NewMacros.length + " new Macro(s), " + NewExamples.length +" new Example(s), " + NewTools.length + " new Tool(s) and " + NewToolsets.length + " new Toolset(s), available on line.";
	} else {Messagenew = message2;}

	if(updates==1) {
		if ((UpdatedMacro.length + UpdatedTool.length + UpdatedToolsets.length + UpdatedExamples.length) > 0) {
			messageupdat="- There are "+ UpdatedMacro.length + " Macro(s), "+ UpdatedExamples.length + " Example(s), " + UpdatedTool.length +" Tool(s) and "+ UpdatedToolsets.length +" Toolset(s), updates available on line.";
		} else {messageupdat= message1;}
	} else {messageupdat = message3;} 
	continue = "";
	if ((messageupdat != message3) ||  (Messagenew != message2)) continue = " \n-> Perform the installation?";
	if ((Messagenew== message2) && (messageupdat== message1)) exit("No new macro, example, tool or toolset update available: your ImageJ Macro folder is up to date.");
	showProgress(1.0);
	showMessageWithCancel("Installation User Confirmation",Messagenew +"\n"+ messageupdat + "\n"+ continue);
	if (continue == "") exit;
	// To perform the installation of the new macros and tools.
	if ((NewMacros.length + NewTools.length + NewToolsets.length + NewExamples.length) > 0) {
		installFile(NewMacros,distantmacrosrep,macrosfolder);
		installFile(NewTools,distanttoolsrep,macrostoolslocation);
		installFile(NewToolsets,distanttoolsetsrep,macrostoolsetlocation);
		installFile(NewExamples,distantmacrosexamplerep,macrosexamplelocation);
	}
	// To update the macros and tools.
	if (updates==1) {
		if ((UpdatedMacro.length + UpdatedTool.length + UpdatedToolsets.length + UpdatedExamples.length) > 0) {
			archmacros(UpdatedMacro,macrosfolder,"Archived Macros");
			archmacros(UpdatedTool,macrostoolslocation,"Archived Tools");
			archmacros(UpdatedToolsets,macrostoolsetlocation,"Archived Toolsets");
			archmacros(UpdatedExamples,macrosexamplelocation,"Archived Examples");
			installFile(UpdatedMacro,distantmacrosrep,macrosfolder);
			installFile(UpdatedTool,distanttoolsrep,macrostoolslocation);
			installFile(UpdatedToolsets,distanttoolsetsrep,macrostoolsetlocation);
			installFile(UpdatedExamples,distantmacrosexamplerep,macrosexamplelocation);
		}
	}
	// To make the installation report. 
	if (report==1) rapport (FMacros,FTools,FToolsets,FExamples,lMacro,lMacroExample,lTool,lToolsets,NewMacros,NewExamples,NewTools,NewToolsets,UpdatedMacro,UpdatedExamples,UpdatedTool,UpdatedToolsets,macrosfolder,"Update reports");
	if (alert==1) showMessage ("Restart ImageJ to finish the installation of the macros resources.");
}
	// Contents of arrays:
	// FMacros, FTools ; lists of macros and tools into your ImageJ.
	// lMacro, lTool, lToolsets ; lists of macros, tools and toolsets into the online ImageJ macro list or ImageJ repertory.
	// NewMacros, NewTools, NewToolsets ; lists new macros, tools and toolsets available the online ImageJ macro list.
	// UpdatedMacro, UpdatedTool, UpdatedToolsets, UpdatedExamples; lists of macros , tools and toolsets updates available on the ImageJ web site.

function reSampling (liste,listRejet) {
	compteur=0;
 	for (i=0; i<liste.length; i++) {
 		for (j=0; j<listRejet.length; j++) {
			if (liste[i]==listRejet[j]) {liste[i]="-";compteur ++;}
		} 	
 	}
 	return liste;
}

function lenghtResampled (liste) {
	compteur=0;
	for (i=0; i<liste.length; i++) {
		if (liste[i] !="-") {compteur ++;}
	} 
	return compteur;
}

function listResampled (list1,list2) {
	compteur=0;
	for (i=0; i<list1.length; i++) {
		if (list1[i] !="-") {list2 [compteur] = list1 [i]; compteur ++;}
	} 
	return list2;
}

function GetTheListofAvailableMacros () {
	showMessageWithCancel ("Get on line available macros list?");
	netTest ();
	run("URL...", "url=["+urllist+"]");
}

function GetTheListofAvailableMacrosweb () {
	listofwebmacros=getListOfOnlineMacros (1);
	// from PrintToTextWindow macro available at the http://rsbweb.nih.gov/ij/macros/PrintToTextWindow.txt
	// author: Wayne Rasband
	title1 = "ListOfMacros";
	title2 = "["+title1+"]";
	f = title2;
	if (isOpen(title1)) {
		print(f, "\\Update:"); // clears the window
  		print(f, listofwebmacros);
		selectWindow (title1);
	} else {
		run("New... ", "name="+title2+" type=[Text File] width=80 height=16");
  		print(f, listofwebmacros);
	}
}

// lut part
function LUTsUpdater () {
	distantmacrolink = urllistoflut;  checkLocation ();
	message="The updater allows to visualize the LUTs on a\"ramp\", or their effects onto an image.";
	Dialog.create("Lut Updater User Options");
	Dialog.addMessage(message);
	Dialog.addChoice("Choose the visualization ->",newArray("Ramp","Image","Palette","No Visualize"),visuchoice);
	Dialog.addChoice("Choose the update method",updateMethods ,updateMethod);
	Dialog.addCheckbox("Update report?", 1);
	Dialog.show();
	visuchoice=Dialog.getChoice();
	updateMethod=Dialog.getChoice();
	lutreport= Dialog.getCheckbox();
	netTest ();	
	// To get the contents of the distant list of luts.
	showStatus("Internet link...");
	if (updateMethod == updateMethods[0]) {
		showStatus("Internet link...");
		luttextnih =File.openUrlAsString(distantmacrolink);
		showStatus("");
	}
	if (updateMethod == updateMethods[1]) {
		showStatus("Internet link...");
		luttextnih =getListOfOnlineLuts (0);
		showStatus("");
	}	
	lines=split(luttextnih,"\n");nLuts=GetnLUTs (lines,"");
	lLuts = newArray(nLuts);lLuts=llutPlace (lines,lLuts,"");
	if (getDirectory("startup") == 0) exit ("Unable to find the startup directory, something wrong in the ImageJ folder.\nTry again after restarting Image.");
	ijpath = getDirectory("startup");//lutpath=ijpath+"luts/";
	lutpath=ijpath+"luts"+File.separator;
	uninstalledLutPath = lutpath + "luts uninstalled" + File.separator;
	if (File.isDirectory(lutpath) == 0) {
		LutDir = lutpath +File.separator;
		File.makeDirectory(LutDir);
		if (!File.exists(LutDir)) exit ("Unable to create the \" luts \" directory, something wrong in the ImageJ folder.\nTry again after restarting Image.");
	}
	// get elements uninstalled
	listofUninstalledLuts = getFileList(uninstalledLutPath); nUninstalledLuts=GetnLUTs (listofUninstalledLuts,"");
	lUninstalledLuts=newArray(nUninstalledLuts); lUninstalledLuts = llutPlace (listofUninstalledLuts,lUninstalledLuts,"");
	// get local luts installed 
	listoflut = getFileList(lutpath);nlocallut=GetnLUTs (listoflut,"");
	llocalLuts = newArray(nlocallut+nUninstalledLuts);llocalLuts=llutPlace (listoflut,llocalLuts,"");
	for (i=0; i<lUninstalledLuts.length; i++) {llocalLuts [i+nlocallut] = lUninstalledLuts[i];}
	// extract lists of differents kinds of online lut from the list
	nDistribLut=0; nCollectionLut=0; nOtherLut=0;
	nDistribLut = GetnLUTs (lLuts,"Distribution Lut: "); lDistribLut = newArray (nDistribLut); lDistribLut = llutPlace (lLuts,lDistribLut,"Distribution Lut: ");
	nCollectionLut = GetnLUTs (lLuts,"Main Collection Lut: "); lCollectionLut = newArray (nCollectionLut); lCollectionLut = llutPlace (lLuts,lCollectionLut,"Main Collection Lut: ");
	nOtherLut = GetnLUTs (lLuts,"Other Lut: "); lOtherLut = newArray (nOtherLut); lOtherLut = llutPlace (lLuts,lOtherLut,"Other Lut: ");
	nNewDistribLut=0; nNewCollectionLut=0; nNewOtherLut=0;
	nNewDistribLut = lDistribLut.length - nbThings(lDistribLut,llocalLuts); lNewDistribLut=newArray (nNewDistribLut); lNewDistribLut = PlaceNewThings (lDistribLut,llocalLuts,lNewDistribLut);
	nNewCollectionLut = lCollectionLut.length - nbThings(lCollectionLut,llocalLuts); lNewCollectionLut=newArray(nNewCollectionLut); lNewCollectionLut = PlaceNewThings (lCollectionLut,llocalLuts,lNewCollectionLut);
	nNewOtherLut =lOtherLut.length - nbThings(lOtherLut,llocalLuts); lNewOtherLut=newArray(nNewOtherLut); lNewOtherLut = PlaceNewThings (lOtherLut,llocalLuts,lNewOtherLut);
	
	if ((lNewDistribLut.length +lNewCollectionLut.length +lNewOtherLut.length) >0) {
		message="Number of new available Lut(s): " + (lNewDistribLut.length +lNewCollectionLut.length +lNewOtherLut.length) + " (" +lNewDistribLut.length + " Distribution Lut(s), ";
		message=message+  lNewCollectionLut.length + " Main Collection Lut(s) " + lNewOtherLut.length + " Other Lut(s))\nPerform the installation? ";
		if (visuchoice != "No Visualize") message = message+ "\n(The scan of new installed Luts can be interrupted by clicking onto the visualisation image window).";
		showMessageWithCancel (message);
	}
	installFile(lNewDistribLut,distribLutFolder,lutpath);
	installFile(lNewCollectionLut,collectionLutFolder,lutpath);
	installFile(lNewOtherLut,otherLutsFolder,lutpath);
	if ((lNewDistribLut.length +lNewCollectionLut.length +lNewOtherLut.length) >0) {
		if (lutreport == 1 ) { lutRapport (lutpath,lNewDistribLut,lNewCollectionLut,lNewOtherLut);}  
		if (visuchoice != "No Visualize") {
			if (visuchoice == "Image") OpenImageLink(0);
			if (visuchoice == "Ramp") makeRamp();
			if (visuchoice == "Palette") {
				listtovisu=newArray (lNewDistribLut.length +lNewCollectionLut.length +lNewOtherLut.length);
  				for (i=0; i<lNewDistribLut.length; i++) {listtovisu[i]= lNewDistribLut[i];}
  				for (i=0; i<lNewCollectionLut.length; i++) {listtovisu[i+lNewDistribLut.length]= lNewCollectionLut[i];}
  				for (i=0; i<lNewOtherLut.length; i++) {listtovisu[i+lNewDistribLut.length+lNewCollectionLut.length]= lNewOtherLut[i];}
  				lutsPalette (1,listtovisu);
			}
		}
		if (visuchoice != "No Visualize" ) {
			if ((lNewDistribLut.length +lNewCollectionLut.length +lNewOtherLut.length) > 0) {
				if (visuchoice == "Palette") {show=0;} else {show=1;}
				showNewLuts(lutpath,lNewDistribLut,show);
				showNewLuts(lutpath,lNewCollectionLut,show);
				showNewLuts(lutpath,lNewOtherLut,show);
				message="Result of the LUT update process: "+(lNewDistribLut.length +lNewCollectionLut.length +lNewOtherLut.length)+" new LUTs has been installed.\n";
				message=message+"\n \nUse the \"List of new installed LUTS \" from the \"LUTs Updater Menu Tool\" to see again a particular LUT.";				
				message=message+"\n \n(Restart ImageJ to make the LUTs available from the ";
				message=message+"\Image -> Lookup Tables\" menu).";
				showMessage (message);
				UpdateLutList();
			}
		} 
	} else { showMessage ("No new lut available. Your \"luts\" folder is up to date.");}	
}

function lastInstalledLutVisu2() {
	lutlistfile = getDirectory("startup")+"luts"+File.separator+ " LUTs Update Reports"+File.separator+"Last New Installed Luts.txt";
	lastlutlist="";
	if (File.exists(lutlistfile)) lastlutlist=File.openAsString(lutlistfile);
	lines=split(lastlutlist,"\n");
	listOfCommands=newArray(lines.length+8);
	listOfCommands[0]="LUTs Updater";
	listOfCommands[1]="-";
	listOfCommands[2]="Get the static list of available LUTs";
	listOfCommands[3]="Get the list of available LUTs by web exploration";
	listOfCommands[4]="-";
	listOfCommands[5]="Show installed luts as \"Palette\"";
	if (File.exists(lutlistfile)) {listOfCommands[6]="List of new installed LUTs:";listOfCommands[7]="-";} else {listOfCommands[6]="No last luts installed list file found";listOfCommands[7]="-";}
	for (i=0; i<lines.length; i++) {listOfCommands[i+8]=lines[i];}
	return listOfCommands;
}

function GetthelistofavailableLUTs () {
	netTest ();
	showMessageWithCancel ("Get on line available LUTs list?");
	run("URL...", "url=["+urllistoflut +"]");
}

function GetTheListofAvailableLutsweb () {
	listofwebluts=getListOfOnlineLuts (1);
	// from PrintToTextWindow macro available at the http://rsbweb.nih.gov/ij/macros/PrintToTextWindow.txt
	// author: Wayne Rasband
	title1 = "ListOfLuts";
	title2 = "["+title1+"]";
	f = title2;
	if (isOpen(title1)) {
		print(f, "\\Update:"); // clears the window
  		print(f, listofwebluts);
		selectWindow (title1);
	} else {
		run("New... ", "name="+title2+" type=[Text File] width=80 height=16");
  		print(f, listofwebluts);
	}
}

function UpdateLutList() {
	kind="toolsets"; macroname="Luts Macros and Tools Updater.txt";
	macropath=getDirectory("macros") + kind + File.separator+ macroname;
	if (!File.exists(macropath)) exit ("Record this tool into the \"toolsets\" folder with the name \"" +macroname+ "\",\nto use this menu tool.");
	run("Install...", "install=["+macropath+"]");
}

// Function giving the number (NumberOfMacro) of macros and tools contained in a list (lmacros).
function getMacroNumber (lmacros) {
	NumberOfMacro=0;
    for (i=0; i<lmacros.length; i++) {
        showProgress(i,lmacros.length);
		if (endsWith(lmacros[i], ".txt") || endsWith(lmacros[i], ".ijm")) NumberOfMacro ++;	
	}
	return NumberOfMacro;
}

// Function giving the macros number (nMacroinL) the tools number (nToolinL) the toolsets number (nToolsetsinL)  and the example number (nMacroExampleinL) containened in an array (lmacros).
// macros are sorted according .txt or .img and 'Macro' or 'Tool' prefixes.
function getMandTNumber (lmacros) {
	nMacroinL=0;nToolinL=0;nToolsetsinL=0;nMacroExampleinL=0;
    for (i=0; i<lmacros.length; i++) {
         showProgress(i,lmacros.length);
		 if (endsWith(lmacros[i], ".txt") || endsWith(lmacros[i], ".ijm")) {
			if (startsWith(lmacros[i], "Macro ")) nMacroinL ++;
			if (startsWith(lmacros[i], "Tool ")) nToolinL ++;
			if (startsWith(lmacros[i], "Toolset ")) nToolsetsinL ++;
			if (startsWith(lmacros[i], "Example ")) nMacroExampleinL ++;
		}		
	}
}

// Function giving the list of macros (Lele) with the prefix (kind) contained in the list (lmacros).
function lPlace (lmacros,Lele,kind) {
	compteur=0;
    for (i=0; i<lmacros.length; i++) {
        showProgress(i,lmacros.length);
		if (endsWith(lmacros[i], ".txt") || endsWith(lmacros[i], ".ijm")) {
			if (startsWith(lmacros[i], kind)) {
				Lele[compteur]=substring(lmacros[i],lengthOf(kind),lengthOf(lmacros[i]));
				compteur ++;
			}
		}		
	}
	return Lele;
}

// Function setting in the report  (TheReport) the contents of the list (tab), adding the prefix (prefix).
function listit (tab,prefix) {
	for (i=0; i<tab.length; i++) {
		TheReport=TheReport + "\n"+ prefix+tab[i];
	}
}

// Function giving the number of elements contained in the first list (liste1) and in the second list (liste2).
function nbThings(liste1,liste2) {
	compteur=0;
    for (i=0; i<liste1.length; i++) {
		showProgress(i,liste1.length);
		for (j=0; j<liste2.length; j++) {
			if (liste1[i]==liste2[j]) {compteur ++; }
		}
	}
	return compteur;
}

// Function giving the list of elements (New)  contained in the first list (liste1) and NOT contains in the second list (liste2).
function PlaceNewThings (liste1,liste2,New) {
	newcompteur=0;
	test=0;
	for (i=0; i<liste1.length; i++) {
		showProgress(i,liste1.length);
		for (j=0; j<liste2.length; j++) {
			if (liste1[i]==liste2[j]) test ++;
		}
		if (test==0) {
			New[newcompteur]=liste1[i];
			newcompteur ++;
		}
		test=0;
	}
	return New;
}

// Function giving the list of elements (New)  contained in the first list (liste1) and contains in the second list (liste2).
function PlaceDuplicate (liste1,liste2,New) {
	newcompteur=0;
	test=0;
	for (i=0; i<liste1.length; i++) {
		showProgress(i,liste1.length);
		for (j=0; j<liste2.length; j++) {
			if (liste1[i]==liste2[j]) test ++;
		}
		if (test > 0) {
			New[newcompteur]=liste1[i];
			newcompteur ++;
		}
		test=0;
	}
	return New;
}

// Function sorting the number of elements (compteur) which are macros and tools, and can be updated (sorted [n], if n=1 the macro is updatable).
function Nbmacroupdates (macrolocalist,macrodistlist,urlrep,localrep,sorted) {
	compteur=0;
	for (i=0; i<macrolocalist.length; i++) {
		showProgress(i,macrolocalist.length);
		for (j=0; j<macrodistlist.length; j++) {
			if (macrolocalist[i]==macrodistlist[j]) {
				macrotextnih=getdistantmacro1 (macrodistlist[j],urlrep);	
				macropath = localrep + macrolocalist[i];
				if (File.exists(macropath)) {
					thelocalmacro = File.openAsString(macropath);
					if (thelocalmacro != macrotextnih) {
						//if (macrolocalist[i] != "StartupMacros.txt") {
						if (macrolocalist[i] != "StartupMacros.txt" && indexOf(thelocalmacro, "NotUpdateThisFile") <= 0 ) {							
							compteur=compteur+1;
							sorted[i]=1;
						}
					}
				}
			}
		}
	}
	return compteur;
}

// Function giving the list (listupdate) of macros and tools which can be updated.
function placeUpdatemacro(listupdate,locallist,Sorted) {
	compteur=0;
	for (i=0; i<Sorted.length; i++) {
		if (Sorted[i] == 1) {
			listupdate[compteur]=locallist[i];
			compteur++;
		}
	}
	return listupdate;
}

// Function archiving the old macros.
function archmacros(list,localrep,foldername){
	// Create an Archived Tools directory in tools repertory
	if (list.length > 0) {
		ArchDir = localrep+ " " + foldername+File.separator;
		File.makeDirectory(ArchDir);
		if (!File.exists(ArchDir)) exit("Unable to create the "+foldername+" directory, something wrong in the ImageJ folder");
	}
	for (i=0; i<list.length; i++) {
		if (File.exists(localrep+list[i])) {
			thelocalmacro = File.openAsString(localrep+list[i]);
			f= File.open(ArchDir + list[i]);
			print (f,thelocalmacro);
			File.close(f);
		}
	}
}

// Function installing a list (list) of distant macro located at (urlrep), into the local folder (localrep).
function installFile(list,urlrep,localrep){
	for (i=0; i<list.length; i++) {
		showProgress(i,list.length);
		macrotextnih= getdistantmacro1 (list[i],urlrep);
		if (macrotextnih != weberror) {
			f= File.open(localrep + list[i]);
			print (f,macrotextnih);
			File.close(f);
		}
	}
	showProgress(1.0);
}

// Function giving the content of a distant macro (name) located at the distant repertory (urlrep).
function getdistantmacro1 (name,urlrep) {
	distantmacrolink = urlrep + name;
	if (indexOf(distantmacrolink, " ") > -1) {
		while (indexOf(distantmacrolink, " ") > -1) {
			distantmacrolink=substring(distantmacrolink, 0, (indexOf(distantmacrolink, " ")))+"%20"+substring(distantmacrolink, (indexOf(distantmacrolink, " ")+1),lengthOf(distantmacrolink) );
		}
	}
	showStatus("Internet link...");
	macrotextnih =File.openUrlAsString(distantmacrolink);
	if (indexOf(macrotextnih, "<Error:") == 0 ) {macrotextnih= weberror;}
	showStatus("");	
	return macrotextnih;
}

// Function making a detailed report of every list obtained.
function rapport (FMacros,FTools,FToolsets,FExamples,lMacro,lMacroExample,lTool,lToolsets,NewMacros,NewExamples,NewTools,NewToolsets,UpdatedMacro,UpdatedExamples,UpdatedTool,UpdatedToolsets,localrep,foldername) {
	TheReport="";
	getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec);
	reportname=  ""+dayOfMonth+"-"+(month+1) +"-"+year+" at "+hour+"."+minute+"."+second+"";
	TheReport=TheReport + "Installation report for the update performed on: "+reportname;
	if ((NewMacros.length+NewTools.length +NewToolsets.length +NewExamples.length)>0) {
		TheReport=TheReport +"\n\n--- The following new Macros, Examples, Tools and Toolsets have been installed: ";
		TheReport=TheReport + "("+(NewMacros.length+NewTools.length+NewToolsets.length+NewExamples.length)+" Macros: "+NewMacros.length+ " \"macro(s)\", "+ NewExamples.length + " \"example(s)\", " +NewTools.length+" \"tool(s)\" & "+NewToolsets.length+" \"toolset(s)\"):\n";
		listit (NewMacros,"Macro ");
		if (NewMacros.length > 0) TheReport=TheReport + "\n--------";
		listit (NewExamples,"Example ");
		if (NewExamples.length > 0) TheReport=TheReport + "\n--------";
		listit (NewTools,"Tool ");
		if (NewTools.length > 0) TheReport=TheReport + "\n--------";
		listit (NewToolsets,"Toolset ");
		if (NewToolsets.length > 0) TheReport=TheReport + "\n--------";
	}
	if(updates==1) {
		TheReport=TheReport + "\n\n--- The following Macros, Examples, Tools and Toolsets updates have been performed: ";
		TheReport=TheReport +"("+(UpdatedMacro.length+UpdatedTool.length+UpdatedToolsets.length +UpdatedExamples.length)+" Macros: "+UpdatedMacro.length+ " \"macros\", " +UpdatedExamples.length + "\"examples\", "+ UpdatedTool.length+" \"tools\" & "+UpdatedToolsets.length+" \"toolsets\"):\n";
		listit  (UpdatedMacro,"Macro ");
		if (UpdatedExamples.length > 0) {if (UpdatedMacro.length > 0) {TheReport=TheReport + "\n--------";} listit (UpdatedExamples,"Example ");}
		if (UpdatedTool.length > 0) TheReport=TheReport + "\n--------"; listit (UpdatedTool,"Tool ");
		if (UpdatedToolsets.length > 0) TheReport=TheReport + "\n--------"; listit (UpdatedToolsets,"Toolset ");
	}
	if (updates==0) TheReport=TheReport + "\n\n--- The Macros, Examples, Tools and Toolsets updated have not been queried.";
	TheReport=TheReport + "\n\n--- Note: the list of Macros, Examples, Tools and Toolsets installed onto you computer before this update ---";
	TheReport=TheReport + "\n      ("+(FMacros.length+FTools.length+ FToolsets.length + FExamples.length)+" Macros: "+ FMacros.length + " \"macros\", "+ FExamples.length + " \"examples\", "+ FTools.length+ " \"tools\" & "+ FToolsets.length+" \"toolsets\"):";
	listit (FMacros,"Macro ");TheReport=TheReport +"\n--------";listit (FExamples,"Example ");TheReport=TheReport +"\n--------";listit (FTools,"Tool ");TheReport=TheReport +"\n--------";listit (FToolsets,"Toolset ");
	TheReport=TheReport +"\n\n--- Note: the list of Macros, Examples, Tools and Toolsets available at the ImageJ web site ---";
	TheReport=TheReport + "\n      ("+(lMacro.length+lTool.length+ lToolsets.length +lMacroExample.length)+" Macros: "+ lMacro.length + " \"macros\", "+ lMacroExample.length + " \"examples\", " +lTool.length +" \"tools\" & "+ lToolsets.length +" \"toolsets\"):";
	listit (lMacro,"Macro "); TheReport=TheReport +"\n--------"; listit (lMacroExample,"Example ");TheReport=TheReport +"\n--------"; listit (lTool,"Tool ");TheReport=TheReport +"\n--------"; listit (lToolsets,"Toolset ");
	UpdateReports = localrep+ " " + foldername+File.separator;
	File.makeDirectory(UpdateReports);
	if (!File.exists(UpdateReports)) exit("Unable to create the "+foldername+" directory, something wrong in the ImageJ folder");
	f= File.open(UpdateReports + reportname+".txt" );	print (f,TheReport);
	File.close(f);
	if (File.exists(UpdateReports + reportname+".txt")) open(UpdateReports + reportname+".txt");
}

function about1() {
	about="";
	about=about + "The \"Luts Macro and Tools Updater\" ImageJ tool bar icons allow to perfom a live update of the ImageJ";
	about=about + "\n macros and luts repertories.";
	about=about + "\n \n\"Macro, Tools and Toolsets Updater Menu Tool\" ImageJ tool bar icon:";
	about=about + "\n    - \"Macro, Tools and Toolsets Updater\" looks for new and updated macros (including examples),";
 	about=about + "\n       Tools and Toolsets and installs them.";
	about=about + "\n \n\"LUTs Updater Menu Tool\" ImageJ tool bar icon:";
	about=about + "\n    - \"LUTs Updater\" looks for new \"Distribution\", \"Main Collection\" and \"Other\" luts and installs them.";
	about=about + "\n    - Gives a menu of last new installed LUTs, allowing to test them on images or ramps";
	about=about + "\n    - Gives a \"Palette\" of installed LUTs";
	about=about + "\n \n- Click on the \"On Line Documentation\" ImageJ tool bar icon for more details.";
	about=about + "\n- Click on the \"Version Infos\" ImageJ tool bar icon to look for new beta versions.";
	about=about + "\n------------------------------------------------------------------";
	about=about +"\nAuthor : Gilles Carpentier"+"\nFaculte des Sciences et Technologies"+"\nUniversite Paris 12 Val de Marne, France.";
	showMessage(about);
}

// function specific to the LUTs Updater

function OpenImageLink(question) {
	demoimalocation = getDirectory("startup");	
	fildestination = demoimalocation+ "Downloaded Demo Images/" +demoimagename;
	if (File.exists(fildestination) && ! isOpen(demoimagename)) {
		if (question ==1 ) showMessageWithCancel ("The \"" + demoimagename + "\" has already been downloaded. Open it?");
		open(fildestination);
	}
	else {
		if (! isOpen(demoimagename)) { run("Blobs (25K)"); }
		selectImage(demoimagename);
		nomdimage = getTitle;
		// Create a <Downloaded Demo Images> repertory in ImageJ folder.
		ImaDemo = demoimalocation+"Downloaded Demo Images"+File.separator;
		File.makeDirectory(ImaDemo);
		if (!File.exists(ImaDemo)) exit("Unable to create directory, something wrong in the ImageJ folder");
		selectWindow(nomdimage);
		save(""+ImaDemo+""+ nomdimage +"");
	}
}

function lutRapport (cheminlut,listeDist,listeCollec,ListeOther) {
	lutrapport="";LastLuts="";
	getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec);
	reportname=  ""+dayOfMonth+"-"+(month+1) +"-"+year+" at "+hour+"."+minute+"."+second+"";
	lutrapport=lutrapport + "Installation report for the LUT update performed on: "+reportname;
	lutrapport=lutrapport +"\n \nThe following "+(listeDist.length + listeCollec.length + ListeOther.length) + " new LUTs has been installed into the \""+cheminlut+ "\"repertory of ImageJ:\n";	

	if (listeDist.length>0) lutrapport= lutrapport+ "\n\n---------------\nDistribution Luts:\n---------------\n";
	for (i=0; i<listeDist.length; i++) {
		lutrapport= lutrapport + "\nLut name: " + listeDist[i] ;
		LastLuts=LastLuts  + ShortName (listeDist[i]) + "\n";
	}	
	if (listeCollec.length>0) lutrapport= lutrapport+ "\n\n------------------\nMain Collection Luts:\n------------------\n";
	for (i=0; i<listeCollec.length; i++) {		
		lutrapport= lutrapport + "\nLut name: " + listeCollec[i] ;
		LastLuts=LastLuts  + ShortName (listeCollec[i]) + "\n";
	}
	if (ListeOther.length>0) lutrapport= lutrapport+ "\n\n----------\nOther Luts:\n----------\n";
	for (i=0; i<ListeOther.length; i++) {
		lutrapport= lutrapport + "\nLut name: " + ListeOther[i] ;
		LastLuts=LastLuts  + ShortName (ListeOther[i]) + "\n";
	}	
	foldername="LUTs Update Reports";
	LutUpdateReports = cheminlut+ " " + foldername+File.separator;
	File.makeDirectory(LutUpdateReports);
	if (!File.exists(LutUpdateReports)) exit("Unable to create the "+foldername+" directory, something wrong in the ImageJ folder");
	f= File.open(LutUpdateReports + reportname+".txt" );	print (f,lutrapport);
	File.close(f);
	f= File.open(LutUpdateReports + "Last New Installed Luts.txt" );	print (f,LastLuts);
	File.close(f);
	if (File.exists(LutUpdateReports + reportname+".txt")) open(LutUpdateReports + reportname+".txt");
}

// Function giving the number of LUTs in a list with filter in kind
function GetnLUTs (lutlist,kind) {
	NumberOfLUTs=0;
    for (i=0; i<lutlist.length; i++) {
        showProgress(i,lutlist.length);
		if (endsWith(lutlist[i], ".lut")) {
			if (kind == "") {
				NumberOfLUTs ++;
			} else {
				if ((startsWith(lutlist[i], kind) ) && (kind != "")) {NumberOfLUTs ++;}
			}
		}
	}
	showProgress(1.0); return NumberOfLUTs;
}

// Function giving the list of elements (Lele) with the sufix ".lut" contained in the list (llut) with filter in kind.
function llutPlace (llut,Lele,kind) {
	compteur=0;
    for (i=0; i<llut.length; i++) {
        showProgress(i,llut.length);
		if (endsWith(llut[i], ".lut")) {
			if (kind == "") {
				Lele[compteur]=llut[i];compteur ++;
			} else {
				if ((startsWith(llut[i], kind) ) && (kind != "")) {Lele[compteur]=replace(llut[i], kind, "");compteur ++;}
			}
		}	
	}
	showProgress(1.0); return Lele;
}

// function opening the new luts
function showNewLuts(cheminLut,lNewlut,show) {
	setTool(10);nomderampe = getTitle; 
    for (i=0; i<lNewlut.length; i++) {
		if (show ==1 && stopthemacro == 0) {
			open(cheminLut + lNewlut[i]);
			rename(lNewlut[i]);
			wait(500);
		}
	}
	rename (nomderampe);
}

function makeRamp () {
	setBatchMode(true);
	if (! isOpen("LUTs visualisation")) { 
		newImage("LUTs visualisation", "8-bit ramp", 256, 32,1);
	} else {selectImage("LUTs visualisation");}
	nomderampe = getTitle;
	setBatchMode("exit and display");
	return nomderampe;
}

function checkForImage (cmd) {
	imaname="";
	if (nImages > 0) {
		setBatchMode(true);visu=0;depth = bitDepth;imaname= getTitle;ok=0;
		if (depth > 8) {
			showMessage("Color tables cannot be assigned to RGB image.\nThe lut will be drawed on a \"ramp\" window,\nor applied to the demo image.");
			rampname= lookForaRamp ();
			if  (rampname == "") {makeRamp ();selectImage("LUTs visualisation");imaname= getTitle;depth = bitDepth;ok=1;}
			if  (rampname != "" && ok==0) {selectImage(rampname);imaname= getTitle;depth = bitDepth;ok=1;}
		} 
		if (depth == 8 && startsWith(imaname, "LUTs :" ) && ok==0) ok=1;
        if (depth == 8 && imaname == demoimagename)  ok=1;
        if (depth == 8 && imaname == "LUTs visualisation")  ok=1;
		selectImage (imaname);
		if (ok ==1 && depth ==8) {rename ("LUTs : " + cmd);}
		imaname= getTitle;
		setBatchMode("exit and display");
	}
	return imaname;	
}

function lookForaRamp () {
	rampansvers = "";
	if (nImages > 0) {
		for (i=1; i <= nImages; i++) {
				selectImage(i);imaname=getTitle;
				if (bitDepth == 8 && startsWith(imaname, "LUTs :")) {rampansvers=imaname;}
			} 
		}
	return rampansvers;
}

function ShortName (longname) {
	if (endsWith(longname, ".txt") || endsWith(longname, ".ijm") || endsWith(longname, ".lut")) longname = substring(longname, 0, (lengthOf(longname)-4));
	return longname;
}

function netTest () {
	if (indexOf (File.openUrlAsString(urllist), errorNetMessage) >0) exit("You need an internet access to run this function.");
}

// functions to get the macros and luts list from the web repertoties

function getListOfOnlineLuts (user) {
	// if user = 0, list without numbers
	showStatus("Internet link...");
	totallutnumber=0; comment="";
	List.clear; 
	comment ="Distribution Lut: ";
	distribLuts=extractLinesFromfolder (distribLutFolder,comment,"<A","</A","=\"",".lut\"",totallutnumber);
	totallutnumber=totallutnumber+distribLuts[1];
	comment ="Main Collection Lut: ";
	collectionLuts=extractLinesFromfolder (collectionLutFolder,comment,"<A","</A","=\"",".lut\"",totallutnumber);
	totallutnumber=totallutnumber+collectionLuts[1];
	comment ="Other Lut: ";
	otherLuts=extractLinesFromfolder (otherLutsFolder,comment,"<A","</A","=\"",".lut\"",totallutnumber); 
	totallutnumber=totallutnumber+otherLuts[1];	
	lutlist="";
	if (user == 1) {
		lutlist="-------- "+ List.size +" Luts available at the Image.Bio.Image web site: --------";
		lutlist=lutlist+"\n(" + (distribLuts[1] + collectionLuts[1]+ otherLuts[1]) +" Luts: "+ distribLuts[1]+ " \"Distribution Luts\", "+collectionLuts[1]+ " \"Main Collection Luts\", "+otherLuts[1]+ " \"Other Luts\":\n\n";
		for (i=1; i<= List.size; i++) lutlist = lutlist + pad(i) + ": " + List.getValue(i) + "\n";
	}
	if (user == 0) {
		lutlist="-------- "+ List.size +" Luts available at the Image.Bio.Image web site: --------";
		lutlist=lutlist+"\n(" + (distribLuts[1] + collectionLuts[1]+ otherLuts[1]) +" Luts: "+ distribLuts[1]+ " \"Distribution Luts\", "+collectionLuts[1]+ " \"Main Collection Luts\", "+otherLuts[1]+ " \"Other Luts\":\n\n";
		for (i=1; i<= List.size; i++) lutlist = lutlist  + List.getValue(i) + "\n";
	}
	return lutlist;
}

function getListOfOnlineMacros (user) {
	// if user = 0, list without comments	
	showStatus("Internet link...");
	totalMacroNumber=0;
	List.clear;
	projectsMacro=extractLinesFromfolder (macrosFolder,"Macro ","<a","</a",">",".txt",totalMacroNumber);
	totalMacroNumber=totalMacroNumber+projectsMacro[1];
	projectsExample=extractLinesFromfolder (exampleFolder,"Example ","<a","</a",">",".txt",totalMacroNumber);
	totalMacroNumber=totalMacroNumber+projectsExample[1];
	projectsTool=extractLinesFromfolder (toolsFolder,"Tool ","<a","</a",">",".txt",totalMacroNumber);
	totalMacroNumber=totalMacroNumber+projectsTool[1];
	projectsToolset=extractLinesFromfolder (toolsetsFolder,"Toolset ","<a","</a",">",".txt",totalMacroNumber);
	totalMacroNumber=totalMacroNumber+projectsToolset[1];
	macroliste="";
	if (user == 1) {
		macroliste="-------- "+ List.size +" Macros and Tools available at the ImageJ web site: --------";
		macroliste=macroliste+"\n(" + (projectsMacro[1] + projectsExample[1]+ projectsTool[1] + projectsToolset[1]) +" Macros: "+ projectsMacro[1]+ " \"macros\", "+projectsExample[1]+ " \"examples\", "+projectsTool[1]+ " \"tools\", "+ projectsToolset[1]+ " \"toolsets\"):\n\n";
		for (i=1; i<= List.size; i++) macroliste = macroliste + pad(i) + ": " + List.getValue(i) + "\n";
	}
	if (user == 0) {
		for (i=1; i<= List.size; i++) macroliste = macroliste + List.getValue(i) + "\n";
	}
	return macroliste;
}

// function extracting the lines containing a text file name (.txt) from the ImgageJ macros web repertories 
function extractLinesFromfolder (urlfolder,kindOfThing,tag1,tag2,tag3,discriminant,total) {
	folderContents =File.openUrlAsString(urlfolder);
	folderContentLines=split(folderContents,"\n");
	listOfThings=""; nbrthings=0;
	for (i=0; i<folderContentLines.length; i++) {
		titleCandidat=extractFromLine (folderContentLines[i],tag1,tag2);
		titleCandidat=extractFromLine (titleCandidat,tag3,discriminant);
		titleCandidat=replace(titleCandidat, "%20", " ");		
		if (titleCandidat != "") {
			nbrthings++;  total++;
			List.set(total, kindOfThing + titleCandidat); 
			listOfThings=listOfThings + kindOfThing + titleCandidat+"\n";  // list in a variable
		}
	}
	listOfElements=newArray (2);
	listOfElements[0]=listOfThings; listOfElements[1]=nbrthings;
	return listOfElements;
}

//function extracting from a line, a substring comprised between prefixe and sufixe
function extractFromLine (line,prefixe,sufixe) {
	pieceOfLine="";
	if (indexOf(line,prefixe) >0 && lastIndexOf(line,sufixe) >0)  {
		pieceOfLine= substring(line, indexOf(line, prefixe)+lengthOf(prefixe), lastIndexOf(line, sufixe)+lengthOf(sufixe));
		if (endsWith(pieceOfLine, "\"")) {pieceOfLine= substring(pieceOfLine, 0,lastIndexOf(pieceOfLine, "\""));}
	}
	return pieceOfLine;
}

// from http://rsb.info.nih.gov/ij/macros/Process_Virtual_Stack.txt  Author: Wayne Rasband
function pad(n) {
	str = toString(n);
	while (lengthOf(str)<3) str = "0" + str;
	return str;
}

function checkLocation () {
	kind="toolsets"; macroname="Luts Macros and Tools Updater.txt";
	macropath=getDirectory("macros") + kind + File.separator+ macroname;
	if (!File.exists(macropath)) showMessageWithCancel ("Record this tool into the \"toolsets\" folder with the name \"" +macroname+ "\",\nto to obtain full functionalities.");
}

function lutsPalette (update,listToShow) {
	// from Show_All_LUTs code author: Gerome Mutterer
	// This macro displays, as a montage, all the LUTs in the luts folder.	 
	saveSettings();
	lutdirname="luts";
	lutdir=getDirectory("startup")+lutdirname+File.separator;
	if (!File.exists(lutdir)) exit("The 'luts' folder not found in the ImageJ folder");	
	if (update == 0) listToShow = getFileList(lutdir); 
	if (listToShow.length < 1) exit ("No lut found in the 'luts' folder");
	setBatchMode(true);
	if (isOpen (lutdir+" - Palette")) {selectWindow (lutdir+" - Palette"); close ();}
	newImage("ramp", "8-bit Ramp", 256, 32, 1);
	newImage("luts", "RGB White", 256, 48, 1);
	count = 0;
	setForegroundColor(255, 255, 255);
	setBackgroundColor(255, 255, 255);
	for (i=0; i<listToShow.length; i++) {
  		if (endsWith(listToShow[i], ".lut")) {
      		selectWindow("ramp");
      		open(lutdir+listToShow[i]);
      		run("Select All");
      		run("Copy");
      		selectWindow("luts");
      		makeRectangle(0, 0, 256, 32);
      		run("Paste");
      		setJustification("center");
      		setColor(0, 0, 0);
      		drawString(listToShow[i],128, 48);
      		run("Add Slice");
            run("Select All");  
     		run("Clear", "slice");  
      		count++;
 		 }
	}
	run("Delete Slice");
	rows = floor(count/4);
	run("Canvas Size...", "width=258 height=50 position=Center");
	if (rows<count/4) rows++;
	if (nSlices >1) {
		run("Make Montage...", "columns=4 rows="+rows+" scale=1 first=1 last="+count+" increment=1 border=0 use");
		if (update==0) {rename(lutdir+" - Palette");} else {rename("Last installed Luts - Palette");}
	}
	else {
    	selectWindow("luts");    	
    	rename("Single lut in the 'luts' folder");
	}
	setBatchMode(false);
	restoreSettings();
}
	
function endinstall (nomdetool,nomdedev,locdev,destidev,folderplugin) {
	pluginname =""; Starter =""; delshortcut=0; movedev=0; installation=0;
	var kind="toolsets/"; 
	var favoritefoldername= "Macros";
	//move the nomdedev at locdev ij repertory to the destidev ij repertoty, and rename it as nomdetool
	if (getDirectory("startup") == 0) exit ("Unable to find the startup directory, something wrong in the ImageJ folder");
	if (getDirectory("macros") == 0) exit ("Unable to find the macros directory, something wrong in the ImageJ folder");	
	MacroPath=getDirectory("macros");
	macropath1=MacroPath+locdev +File.separator+nomdedev;
	macropath2=MacroPath+kind+nomdetool;
	if ( File.exists(macropath1)) {movedev=File.rename(macropath1, macropath2); } 		
	// removed old plugin shortcuts, image.bio.methods folder, and install nomdetool plugin shortcut.
	removeOldShortcuts (folderplugin, nomdedev, "");
	removeOldShortcuts ("My Favorite Macros", nomdedev, "");
	removeOldShortcuts ("My Favorite Macros", nomdetool, "toolsets");
	removeOldShortcuts ("Image.Bio.Methods", nomdetool, "");
	removeOldShortcuts ("Image.Bio.Methods", nomdedev, "");
	if (File.isDirectory(getDirectory("plugins")+"Image.Bio.Methods"+File.separator)) {path=getDirectory("plugins")+"Image.Bio.Methods"+File.separator;a=File.delete(path);}
	// archive the original tool
	UpdatedMacro=newArray(1); UpdatedMacro [0]=nomdetool; macrosfolder=MacroPath+locdev +File.separator;
	oripath=MacroPath+locdev +File.separator+nomdetool;
	if (File.exists(oripath)) {
		code=File.openAsString(oripath);
		if (indexOf (code,"NotUpdateThisFile") < 0 ) {
			archmacros(UpdatedMacro,macrosfolder,"Archived Tools");
			if (File.exists(oripath)) deloriginal =File.delete(oripath);
		}
	}	
	// create the plugin shortcut
	findcode="";
	if (endsWith(nomdetool, ".txt") || endsWith(nomdetool, ".ijm")) pluginname2 = substring(nomdetool, 0, (lengthOf(nomdetool)-4));
	pathstartertest= getDirectory("plugins")+folderplugin+File.separator+pluginname2 +"_ .ijm";
	if ( File.exists(pathstartertest)) findcode= File.openAsString(pathstartertest);
	if (indexOf (findcode,kind) < 0 && indexOf (findcode,nomdetool) < 0) {InstallPluginsStarter(nomdetool);installation=1;}
	// install the new macro
	if (installation ==1) {if (File.exists(macropath2)) {run("Install...", "install=["+macropath2+"]");}}
}

function removeOldShortcuts (nomDeFolder, nomDeDev, filter) {
	if (getDirectory("plugins") == "") exit ("Unable to find the Plugins directory; something wrong in the ImageJ folder.");
	if (endsWith(nomDeDev, ".txt") || endsWith(nomDeDev, ".ijm")) pluginname = substring(nomDeDev, 0, (lengthOf(nomDeDev)-4));
	Starter = getDirectory("plugins")+nomDeFolder+File.separator+pluginname +"_ .ijm";
	if (File.exists(Starter)) {
		if (filter != "") {
			findcode= File.openAsString(Starter);
			if (indexOf (findcode,filter) < 0) delshortcut =File.delete(Starter);	
		} else {delshortcut =File.delete(Starter);}
	}
}	
	
// --- End of code of the macro project ---//
// ----------------------------------//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// -------------------*** Additionnal code for on line update resources ***-----------------------------
//Developer info
//Kind:Toolset
//Title:"Luts Macros and Tools Updater" 
//Version:1.1a
//Date:3 July 2009
//Origin:Image.Bio.Methods
//NotUpdateThisFile
//End info

function VersionInfos () {
	// variables for on line update resources
	beginsign="//Developer info";endsign="//End info"; 
	kind="toolsets/"; 
	urlrep="http://image.bio.methods.free.fr/ij/ijmacro/macroupdater/";
	name="Luts Macros and Tools Updater.txt"; 
	namedev="Luts Macros and Tools Updater.txt"; 
	favoritefoldername= "Macros";

	version=versionMessage();
	if (indexOf(version, "install it?" ) > 0 ) {
		macrotext=getdistantmacro (namedev,urlrep);macrolocal="";
		macropath=getDirectory("macros")+kind+namedev;
		if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);}
		if (macrotext != macrolocal) {
			//perfom the installation
			Dialog.create("New version installation option");
			Dialog.addMessage(version);
			Dialog.addCheckbox("Install a Plugin Shortcut?", 0);
			Dialog.addMessage("(This option provides a shortcut in the plugins menu of ImageJ, making easier\nthe next use of the new installed version).");
			Dialog.show();
			plugin= Dialog.getCheckbox();
			f= File.open(macropath);
			print (f,macrotext);
			File.close(f);
			if (plugin ==1) {InstallPluginsStarter(namedev);}
			message="The installation of the "+giveDevInfo (macrotext,1)+ " "+ giveDevInfo (macrotext,2)+ "is completed.";
			message=message+"\nThis new version will be available from the \"Toolsets\" menu tool \">>\" at the right of the ImageJ tool bar.";
			message=message+ "\nDo you want to run it?";
			showMessageWithCancel(message);
			run("Install...", "install=["+macropath+"]");
		}
	} else {showMessage (version); // comment without installation available}
}

function versionMessage() {	
	version="";
	if (getDirectory("startup") == 0) exit ("Unable to find the startup directory, something wrong in the ImageJ folder");
	if (getDirectory("macros") == 0) exit ("Unable to find the macros directory, something wrong in the ImageJ folder");
	MacroPath=getDirectory("macros");thismacropath=MacroPath+kind+name;
	if (! File.exists(thismacropath)) exit ("This macro has to be recorded under the name of \"" +name+"\"\ninto the \"macros/"+kind+"\" folder of ImageJ.");
	macrotext=File.openAsString(thismacropath);
	macrotextdistant=getdistantmacro (namedev,urlrep);
	version="";macrolocal="";
	version=version + "\n \nThis version of the " + giveDevInfo (macrotext,1) + " " + giveDevInfo (macrotext,2);
	version=version + "is provided by the " + giveDevInfo (macrotext,5)+ " web site.";
	version=version + "\nVersion number: " + giveDevInfo (macrotext,3)+ " - " + giveDevInfo (macrotext,4) +".";	
	if (macrotextdistant !="" ) {
		new=giveDevInfo (macrotextdistant,3);old=giveDevInfo (macrotext,3);
		if (new > old) {
			macropath=getDirectory("macros")+kind+namedev;
			if (File.exists(macropath)) {macrolocal=File.openAsString(macropath);}
			if (macrotextdistant != macrolocal) {
				update="\n \nA new version "+new+ " is available on the "  +giveDevInfo (macrotextdistant,5)+ " web site: ";
				update=update+ "\n \nDo you want to install it?";
			} else {
				update ="\n \nThe new "+new+" latest version called \"" +namedev+ "\" provided by \nthe "+giveDevInfo (macrotextdistant,5) +" web site has already be installed";
				update = update+ " in the \"" +kind+ "\" repertory \nof ImageJ.";
			}
		} else {
			update="No new version available.";
		}
		version=version +"\n" + update ;
	} 
	return version; 
}

function giveDevInfo (text,n) {
	lines=split(text,"\n");
	if ( (indexOf(text, beginsign)<0) || (indexOf(text, endsign)<0) ) exit ("Not upgradable macro code.");
	for (i=0; lines[i] != endsign; i ++) {}
	for (j=i; lines[j] != beginsign; j --) {}
	infotext=newArray(i-j-1);
	for (i=0; i < infotext.length; i ++) {infotext[i]=lines[i+j+1];}
	info=infotext[n-1]; signature=":";
	cut = indexOf(info, signature);
	info = substring(info,(cut+lengthOf(signature)),lengthOf(info));
	return info;
}

// Function giving the content of a distant macro (name) located at the distant repertory (urlrep).
// updated for the version 1.41i
function getdistantmacro (name,urlrep) {
	macrotextnih=""; erNetMessage ="Error: ";
	testlink = "http://rsb.info.nih.gov/ij/macros/Arrays.txt";
	if (indexOf (File.openUrlAsString(testlink), erNetMessage) < 0) {
		distantmacrolink = urlrep + name;
		if (indexOf(distantmacrolink, " ") > -1) {
			while (indexOf(distantmacrolink, " ") > -1) {
				distantmacrolink=substring(distantmacrolink, 0, (indexOf(distantmacrolink, " ")))+"%20"+substring(distantmacrolink, (indexOf(distantmacrolink, " ")+1),lengthOf(distantmacrolink) );
			}
		}
		showStatus("Internet link...");
		macrotextnih =File.openUrlAsString(distantmacrolink);
		showStatus("");
	} else { showMessage ("No internet connection to looks for new version.");}
	return macrotextnih;
}

function InstallPluginsStarter(macroname) {
	// from MacroPluginShortcutsTool.txt
	codestarter = "run\(\"Install...\", \"install=[\"+getDirectory(\"macros\")+\""+kind+ macroname + "\]\"\);";
	if (getDirectory("plugins") == "") exit ("Unable to find the Plugins directory; something wrong in the ImageJ folder.");
	if (endsWith(macroname, ".txt") || endsWith(macroname, ".ijm")) pluginname = substring(macroname, 0, (lengthOf(macroname)-4));
	StarterDir = getDirectory("plugins")+favoritefoldername+File.separator;
	File.makeDirectory(StarterDir);
	if (!File.exists(StarterDir)) exit ("Unable to create "+favoritefoldername+" Macros directory, something wrong in the ImageJ folder.");
	starterplugin = StarterDir + pluginname +"_ .ijm";
	f= File.open(StarterDir + pluginname +"_ .ijm");
	print (f,codestarter);
	File.close(f);
	showMessage ("The plugin shortcut \"" +pluginname+ "\" will be available after\nImageJ restarting, in the \"Plugins->" + favoritefoldername + "\" menu.");
}
// *** End of additionnal code for on line update ressources ***

